/// @tags: DivideBlock
#include <algorithm>
#include <cstdio>
#include <iostream>
#define rint register int

using std::cin;
using std::cout;
using std::max;
using std::min;

namespace BlueQuantum {

constexpr int maxn = 1e5 + 3, block = 320, INF = 0x3f3f3f3f;

struct Node {
  int val, pos;
  inline bool operator<(const Node &rhs) const { return val < rhs.val; }
} sorted[maxn], mer1[block], mer2[block];

int n, m;
int a[maxn];
int L[block], R[block], tag[block], bel[maxn];

inline void init() {
  int tot = (n - 1) / block + 1;
  for (int i = 1; i <= tot; ++i) {
    L[i] = R[i - 1] + 1;
    R[i] = L[i] + block - 1;
  }
  R[tot] = n;
  for (int i = 1; i <= tot; ++i) {
    for (int j = L[i]; j <= R[i]; ++j) bel[j] = i;
    std::sort(sorted + L[i], sorted + R[i] + 1);
  }
}

inline void getLimit(int l, int r, int &minn, int &maxx) {
  int bL = bel[l], bR = bel[r];
  if (bL == bR) {
    for (int i = l; i <= r; ++i) {
      minn = min(minn, a[i] + tag[bL]);
      maxx = max(maxx, a[i] + tag[bL]);
    }
  } else {
    for (int i = l; i <= R[bL]; ++i) {
      minn = min(minn, a[i] + tag[bL]);
      maxx = max(maxx, a[i] + tag[bL]);
    }
    for (int i = L[bR]; i <= r; ++i) {
      minn = min(minn, a[i] + tag[bR]);
      maxx = max(maxx, a[i] + tag[bR]);
    }
    for (int i = bL + 1; i < bR; ++i) {
      minn = min(minn, sorted[L[i]].val + tag[i]);
      maxx = max(maxx, sorted[R[i]].val + tag[i]);
    }
  }
}

inline int solve(int l, int r, int k) {
  int res = 0;
  int bL = bel[l], bR = bel[r];
  if (bL == bR)
    for (int i = l; i <= r; ++i) res += (a[i] + tag[bL] <= k);
  else {
    for (int i = l; i <= R[bL]; ++i) res += (a[i] + tag[bL] <= k);
    for (int i = L[bR]; i <= r; ++i) res += (a[i] + tag[bR] <= k);
    for (int i = bL + 1; i < bR; ++i) {
      int _l = L[i], _r = R[i];
      if (sorted[_l].val + tag[i] > k) continue;
      if (sorted[_r].val + tag[i] <= k) {
        res += _r - _l + 1;
        continue;
      }
      while (_l < _r) {
        int mid = ((_l + _r) >> 1) + 1;
        sorted[mid].val + tag[i] <= k ? _l = mid : _r = mid - 1;
      }
      if (sorted[_l].val + tag[i] <= k) res += _l - L[i] + 1;
    }
  }
  return res;
}

inline int query(int l, int r, int k) {
  int L = INF, R = -INF;
  getLimit(l, r, L, R);
  if (k == 1) return L;
  if (k == r - l + 1) return R;
  if (k < 1 || k > r - l + 1) return -1;
  while (L < R) {
    int mid = (L + R) >> 1;
    solve(l, r, mid) < k ? L = mid + 1 : R = mid;
  }
  return L;
}

inline void modify(int l, int r, int k) {
  int bL = bel[l], bR = bel[r];
  int mcnt1 = 0, mcnt2 = 0;
  for (int i = L[bL]; i <= R[bL]; ++i) {
    if (l <= i && i <= r) a[i] += k;
    if (l <= sorted[i].pos && sorted[i].pos <= r)
      mer1[++mcnt1] = Node{sorted[i].val + k, sorted[i].pos};
    else
      mer2[++mcnt2] = sorted[i];
  }
  int ptr1 = 1, ptr2 = 1;
  int sptr = L[bL];
  while (sptr <= R[bL]) {
    if (ptr1 <= mcnt1 && (ptr2 > mcnt2 || mer1[ptr1].val < mer2[ptr2].val))
      sorted[sptr++] = mer1[ptr1++];
    else
      sorted[sptr++] = mer2[ptr2++];
  }
  if (bL != bR) {
    int mcnt1 = 0, mcnt2 = 0;
    for (int i = L[bR]; i <= R[bR]; ++i) {
      if (i >= l && i <= r) a[i] += k;
      if (sorted[i].pos >= l && sorted[i].pos <= r)
        mer1[++mcnt1] = Node{sorted[i].val + k, sorted[i].pos};
      else
        mer2[++mcnt2] = sorted[i];
    }
    int ptr1 = 1, ptr2 = 1;
    int sptr = L[bR];
    while (sptr <= R[bR]) {
      if (ptr1 <= mcnt1 && (ptr2 > mcnt2 || mer1[ptr1].val < mer2[ptr2].val))
        sorted[sptr++] = mer1[ptr1++];
      else
        sorted[sptr++] = mer2[ptr2++];
    }
    for (int i = bL + 1; i < bR; ++i) tag[i] += k;
  }
}

inline int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    sorted[i] = Node{a[i], i};
  }
  init();
  for (int i = 1; i <= m; ++i) {
    int opt, l, r, k;
    cin >> opt >> l >> r >> k;
    switch (opt) {
      case 1: {
        cout << query(l, r, k) << '\n';
      } break;
      case 2: {
        modify(l, r, k);
      } break;
    }
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P5356 [Ynoi2017] 由乃打扑克.in", "r", stdin);
  freopen("P5356 [Ynoi2017] 由乃打扑克.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
